;___BOOT_LOADER________________________________________________________________________________________________________
;
;  
;  CREATED BY : 	Andrew Lynch 15-FEB-2007
;  MODIFIED by : 	Dan Werner 09.12.2009
;
;______________________________________________________________________________________________________________________


;__Hardware_Interfaces________________________________________________________________________________________________________________ 
;
; PIO 82C55 I/O IS DECODED TO PORT 60-67
;
PORTA		.EQU 	60H
PORTB		.EQU 	61H
PORTC		.EQU 	62H
PIOCONT 	.EQU 	63H
;
; UART 16C450 SERIAL IS DECODED TO 68-6F
;
UART0:		.EQU	68H		;   DATA IN/OUT
UART1:		.EQU	69H		;   CHECK RX
UART2:		.EQU	6AH		;   INTERRUPTS
UART3:		.EQU	6BH		;   LINE CONTROL
UART4:		.EQU	6CH		;   MODEM CONTROL
UART5:		.EQU	6DH		;   LINE STATUS
UART6:		.EQU	6EH		;   MODEM STATUS
UART7:		.EQU	6FH		;   SCRATCH REG.
;
; MEMORY PAGE CONFIGURATION LATCH IS DECODED TO 78
;
MPCL:		.EQU	78H		; CONTROL PORT, SHOULD ONLY BE CHANGED WHILE
;					  IN UPPER MEMORY PAGE $8000-$FFFF OR LIKELY
;					  LOSS OF CPU MEMORY CONTEXT.
;
; MEMORY PAGE CONFIGURATION LATCH CONTROL PORT ( IO_Y3 ) INFORMATION
;
;	7 6 5 4  3 2 1 0      ONLY APPLICABLE TO THE LOWER MEMORY PAGE $0000-$7FFF
;	^ ^ ^ ^  ^ ^ ^ ^
;	: : : :  : : : :--0 = A15 RAM/ROM ADDRESS LINE DEFAULT IS 0
;	: : : :  : : :----0 = A16 RAM/ROM ADDRESS LINE DEFAULT IS 0
;	: : : :  : :------0 = A17 RAM/ROM ADDRESS LINE DEFAULT IS 0
;	: : : :  :--------0 = A18 RAM/ROM ADDRESS LINE DEFAULT IS 0
;	: : : :-----------0 = A19 ROM ONLY ADDRESS LINE DEFAULT IS 0
;	: : :-------------0 = 
;	: :---------------0 = 
;	:-----------------0 = ROM SELECT (0=ROM, 1=RAM) DEFAULT IS 0
;
;
;IDE REGISTER		IO PORT		; FUNCTION
IDELO		.EQU	$20		; DATA PORT (LOW BYTE)
IDEERR		.EQU	$21		; READ: ERROR REGISTER; WRITE: PRECOMP
IDESECTC	.EQU	$22		; SECTOR COUNT
IDESECTN	.EQU	$23		; SECTOR NUMBER
IDECYLLO	.EQU	$24		; CYLINDER LOW
IDECYLHI	.EQU	$25		; CYLINDER HIGH
IDEHEAD		.EQU	$26		; DRIVE/HEAD
IDESTTS		.EQU	$27		; READ: STATUS; WRITE: COMMAND
IDEHI		.EQU	$28		; DATA PORT (HIGH BYTE)
IDECTRL		.EQU	$2E		; READ: ALTERNATIVE STATUS; WRITE; DEVICE CONTROL
IDEADDR		.EQU	$2F		; DRIVE ADDRESS (READ ONLY)
;
FMSR:		.EQU	036H		; ADDRESS OF MAIN STATUS REGISTER
FDATA:		.EQU	037H		; FLOPPY DATA REGISTER
FLATCH:		.EQU	03AH		; FLOPPY CONFIGURATION LATCH
FDMA:		.EQU	03CH		; PSEUDO DMA ADDRESS

;
;
;__Constants_________________________________________________________________________________________________________________________ 
;	

RAMTOP:		.EQU	$FFFF	; HIGHEST ADDRESSABLE MEMORY LOCATION
MONSTART:	.EQU	$8000	; START OF MONITOR
RAMBOTTOM:	.EQU	$8000	; Beginning of Upper 32K RAM page
END:		.EQU	$FF	; Mark END OF TEXT
CR:		.EQU	0DH	; ASCII carriage return character
LF:		.EQU	0AH	; ASCII line feed character
ESC:		.EQU	1BH	; ASCII escape character
BS:		.EQU	08H		; ASCII backspace character


ROMSTART_MON:	.EQU	$0100	; Where the Monitor is stored in ROM
RAMTARG_MON:	.EQU	$8000	; Where the Monitor starts in RAM (entry point)
MOVSIZ_MON:	.EQU	$1000	; Monitor is 2KB in length

ROMSTART_CPM:	.EQU	$1200	; Where the CCP+BDOS+BIOS is stored in ROM
RAMTARG_CPM:	.EQU	$D400	; Where the CCP+BDOS+BIOS starts in RAM (entry point)
MOVSIZ_CPM:	.EQU	$2A00	; CCP, BDOS, + BIOS is 6-7KB in length
STACKTARG:	.EQU	$D3FF	; Where the CCP+BDOS+BIOS starts in RAM (entry point)

Monitor_Entry	.EQU	$8000	; Monitor Entry Point (May change)

;
; FDC CONFIGURATION LATCH OUTPUT BIT PATTERNS
MOTOR:		.EQU	%00000000	; BIT PATTERN IN LATCH FOR MOTOR CONTROL (ON)
TERMCN:		.EQU	%00000001	; BIT PATTERN IN LATCH TO WRITE A TC STROBE
RESETL:		.EQU	%00000010	; BIT PATTERN IN LATCH TO RESET ALL BITS
MINI:		.EQU	%00000100	; BIT PATTERN IN LATCH TO SET MINI MODE FDC9229 LOW DENS=1, HIGH DENS=0
PRECOMP:	.EQU	%00100000	; BIT PATTERN IN LATCH TO SET WRITE PRECOMP 125 NS:
FDDENSITY:	.EQU	%01000000	; BIT PATTERN IN LATCH TO FLOPPY LOW DENSITY (HIGH IS 0)
FDREADY:	.EQU	%10000000	; BIT PATTERN IN LATCH TO FLOPPY READY (P-34):

;______________________________________________________________________________________________________________________
;
; SELECT ONE OF THE FOLLOWING TO BE THE ROOT CONSOLE DEVICE, ONLY ONE CAN BE ACTIVE
;______________________________________________________________________________________________________________________
;
DSKY:		.EQU	0		; 1= ACTIVE, 0=NOT ACTIVE
UART:		.EQU	1		; 1= ACTIVE, 0=NOT ACTIVE
;______________________________________________________________________________________________________________________


;______________________________________________________________________________________________________________________
;	MASKABLE INTERRUPT-PROGRAM
;	Function	:
;	Input		:
;	Output		: 
;	uses		: 
;	calls		: none
;	info		:
;	tested		: 2 Feb 2007
;______________________________________________________________________________________________________________________
;	.ORG	$0038		; Int mode 1
;	RETI			; return from interrupt

;______________________________________________________________________________________________________________________
;	NONMASKABLE INTERRUPT-PROGRAM
;	Function	:
;	Input		:
;	Output		: none
;	uses		: 
;	calls		: none
;	info		:
;	tested		: 2 Feb 2007
;______________________________________________________________________________________________________________________

;	.ORG	$0066		; HERE IS THE NMI ROUTINE
;	RETI



;
;
;
;__Main_Program_____________________________________________________________________________________________________________________ 
;
	.ORG	$0100		; for testing
;	DI			; Disable interrupt
	LD	SP,STACKTARG	; Set stack pointer to top off ram
;	IM	1		; Set interrupt mode 1
;
;	LD	HL,ROMSTART_MON	; where in rom Monitor is stored (first byte)
;       LD	DE,RAMTARG_MON	; where in ram to move Monitor to (first byte)
;	LD	BC,MOVSIZ_MON	; number of bytes to move from ROM to RAM
;	LDIR			; Perform Block Copy of Monitor to Upper RAM page
;
;	LD	HL,ROMSTART_CPM	; where in rom CP/M is stored (first byte)
;       LD	DE,RAMTARG_CPM	; where in ram to move Monitor to (first byte)
;	LD	BC,MOVSIZ_CPM	; number of bytes to move from ROM to RAM
;	LDIR			; Perform Block Copy of CP/M to Upper RAM page
;
;	EI			; enable interrupts (access to Monitor while CP/M running)
	CALL    InitSYSTEM	; Init 
	CALL	SETUPDRIVE	; SETUP FLOPPY PARAMETERS

	JP	DOBOOT		; jump to Start of Monitor

;__DSKY_Init________________________________________________________________________________________
;
;  Setup 8255, Mode 0, Port A=Out, Port B=In, Port C=Out/Out 
;     
;____________________________________________________________________________________________________
InitSYSTEM:
	.IF	DSKY
	LD	A, 82H			;
	OUT 	(PIOCONT),A		;
	.ENDIF
	.IF	UART
	LD	A,12			; specify baud rate 9600 bps (9600,8,None,1)
	LD	(SER_BAUD),A		; 
	CALL	INIT_UART		; INIT the UART 
	.ENDIF
	RET				;
	
;__DoBoot________________________________________________________________________________________________________________________ 
;
;	PERFORM BOOT FRONT PANEL ACTION
;________________________________________________________________________________________________________________________________
;
DOBOOT:
	.IF DSKY

	LD	HL,BOOT			; POINT TO BOOT MESSAGE	
	CALL 	SEGDISPLAY		; DISPLAY MESSAGE
BOOTGETKEY:
	CALL	KB_GET			; Get Key from KB INTO A
	LD	HL,BOOT			; POINT TO BOOT MESSAGE
	PUSH	AF			; STORE AF
	CALL	DECODEDISPLAY		; DECODE "A" TO 7 SEG
	LD	(HL),A			; STORE VALUE IN A TO DISPLAY BUF
	CALL	SEGDISPLAY		; DISPLAY BUFFER ON 7 SEG
	POP	AF			; RESTORE AF
	CP	00H			; [0] PRESSED, BOOT DSKY MONITOR
	JP	Z,8000H			; 
	CP	01H			; [1] PRESSED, BOOT SERIAL MONITOR
	JP	Z,8000H			; 	
	CP	02H			; [2] PRESSED, BOOT ROM CP/M
	JP	Z,0EA00H		; CP/M COLD BOOT ENTRY POINT GOCPM			;
	CP	03H			; [3] PRESSED, BOOT FLOPPY UNIT 0
	JP	Z,BOOTFLOPPYU0		; 	
	CP	04H			; [4] PRESSED, BOOT FLOPPY UNIT 1
	JP	Z,BOOTFLOPPYU1		; 	
	CP	05H			; [5] PRESSED, BOOT IDE PRIMARY
	JP	Z,BOOTIDEPRI		; 
	CP	06H			; [6] PRESSED, BOOT IDE SECONDARY
	JP	Z,BOOTIDESEC		;
	CP	07H			; [7] PRESSED, BOOT ATAPI PRIMARY
	JP	Z,BOOTATAPIPRI		; 
	CP	08H			; [8] PRESSED, BOOT ATAPI SECONDARY
	JP	Z,BOOTATAPISEC		;	
	LD	HL,BOOT			; POINT TO BOOT MESSAGE
	LD	A,00H			; BLANK OUT SELECTION,IT WAS INVALID
	LD	(HL),A			; STORE IT IN DISPLAY BUFFER
	CALL	SEGDISPLAY		; DISPLAY THE BUFFER
	JR	BOOTGETKEY		; NO VALID KEY, LOOP
	.ENDIF
	.IF UART
	LD	HL,MSG_START		;POINT AT TEXT
	CALL	MSG			;SHOW WE'RE HERE
	CALL	CRLFA			; CR,LF,>
	LD	HL,KEYBUF		; SET POINTER TO KEYBUF AREA
	CALL 	GETLN			; GET A LINE OF INPUT FROM THE USER
	LD	HL,KEYBUF		; RESET POINTER TO START OF KEYBUF
        LD      A,(HL)			; LOAD FIRST CHAR INTO A (THIS SHOULD BE THE COMMAND)
	INC	HL			; INC POINTER
	
	CP	'0'			; [0] PRESSED, BOOT DSKY MONITOR
	JP	Z,8000H			; 
	CP	'1'			; [1] PRESSED, BOOT SERIAL MONITOR
	JP	Z,8000H			; 	
	CP	'2'			; [2] PRESSED, BOOT ROM CP/M
	JP	Z,0EA00H		; CP/M COLD BOOT ENTRY POINT GOCPM			;
	CP	'3'			; [3] PRESSED, BOOT FLOPPY UNIT 0
	JP	Z,BOOTFLOPPYU0		; 	
	CP	'4'			; [4] PRESSED, BOOT FLOPPY UNIT 1
	JP	Z,BOOTFLOPPYU1		; 	
	CP	'5'			; [5] PRESSED, BOOT IDE PRIMARY
	JP	Z,BOOTIDEPRI		; 
	CP	'6'			; [6] PRESSED, BOOT IDE SECONDARY
	JP	Z,BOOTIDESEC		;
	CP	'7'			; [7] PRESSED, BOOT ATAPI PRIMARY
	JP	Z,BOOTATAPIPRI		; 
	CP	'8'			; [8] PRESSED, BOOT ATAPI SECONDARY
	JP	Z,BOOTATAPISEC		;	
	JR	DOBOOT			; NO VALID KEY, LOOP	
	.ENDIF
	
	
BOOTFLOPPYU0:
	LD	A,00			; SET UNIT ID
	LD	(UNIT),A		; STORE
	JP	BOOTFLOPPY		;
BOOTFLOPPYU1:
	LD	A,01			; SET UNIT ID
	LD	(UNIT),A		; STORE
BOOTFLOPPY:
	LD	A,00			; 
	LD	(pTRACK),A		; SET TRACK TO 0
	LD	(HEAD),A		; SET HEAD TO 0
	LD	A,03			;
	LD	(SECTOR),A		; SET SECTOR TO 1
			
	LD	HL,0D400H		; SET TOP OF CP/M
	LD	(TEMPW),HL		;
BOOTFLOPPYLOOP:
	CALL	READ_FLOPPY_SECTOR	; READ A SECTOR
	LD	HL,(TEMPW)		;
	LD	BC,0200H		;
	ADD	HL,BC			;
	LD	(TEMPW),HL		;
	LD	A,H			;
	OR	A			;
	JP	Z,BOOTFLOPPYEXIT	;
	LD	A,(SECTOR)		;	
	INC	A			; POINT TO NEXT SECTOR
	LD	(SECTOR),A		;
	CP	0AH			;
	JP	NZ,BOOTFLOPPYLOOP	; LOOP
	LD	A,01			;
	LD	(SECTOR),A		; SET SECTOR TO 1
	LD	A,(HEAD)		;
	INC	A			;
	LD	(HEAD),A		;
	CP	02H			;
	JP	NZ,BOOTFLOPPYLOOP	; LOOP
	LD	A,00			;
	LD	(HEAD),A		; SET HEAD TO 1
	LD	A,(pTRACK)		;
	INC	A			;
	LD	(pTRACK),A		;
	CP	02H			;
	JP	NZ,BOOTFLOPPYLOOP	; LOOP
BOOTFLOPPYEXIT:	
	JP	0EA00H			; GO TO CP/M
BOOTATAPIPRI:
	LD	A,00H
	LD	(IDEDEVICE),A		; SET PRIMARY DEVICE
	JR	BOOTATAPI		;
BOOTATAPISEC:
	LD	A,10H			;
	LD	(IDEDEVICE),A		; SET SECONDARY DEVICE
BOOTATAPI:
	CALL	IDE_SOFT_RESET		;
	CALL	ATAPI_DEVICE_SELECTION	;
	CALL	DELAY12			;
	CALL 	REQUEST_SENSE_LOOP	;
	.IF DSKY
	LD	HL,SEC			; DISPLAY PROMPT
	CALL	SEGDISPLAY		; 
	.ENDIF
	LD	DE,0000H		; SET SECTOR HIGH WORD TO 00H
	LD	HL,0003H		; SET SECTOR LOW WORD TO 03H
	LD	IX,0D400H		; SET TOP OF CP/M
	LD	B,21			; SET NUMBER OF SECTORS TO LOAD
BOOTATAPILOOP:
	.IF DSKY
	CALL	DSPSECTOR		;
	.ENDIF
	CALL	ATAPI_READ_SECTOR	; READ A SECTOR
	INC	HL			; POINT TO NEXT SECTOR
	DJNZ	BOOTATAPILOOP		; LOOP
	JP	0EA00H			; GO TO CP/M
BOOTIDEPRI:
	LD	A,00H
	LD	(IDEDEVICE),A		; SET PRIMARY DEVICE
	JR	BOOTIDE			;
BOOTIDESEC:
	LD	A,10H			;
	LD	(IDEDEVICE),A		; SET SECONDARY DEVICE
BOOTIDE:
	CALL	IDE_SOFT_RESET		;
	.IF DSKY
	LD	HL,SEC			; DISPLAY PROMPT
	CALL	SEGDISPLAY		; 
	.ENDIF
	LD	DE,0000H		; SET SECTOR HIGH WORD TO 00H
	LD	HL,0003H		; SET SECTOR LOW WORD TO 03H
	LD	IX,0D400H		; SET TOP OF CP/M
	LD	B,21			; SET NUMBER OF SECTORS TO LOAD
BOOTIDELOOP:
	PUSH	BC			;
	PUSH	HL			;
	.IF DSKY
	CALL	DSPSECTOR		;
	.ENDIF
	CALL	IDE_READ_SECTOR		; READ A SECTOR
	POP	HL
	INC	HL			; POINT TO NEXT SECTOR
	POP	BC			;
	DJNZ	BOOTIDELOOP		; LOOP
	JP	0EA00H			; GO TO CP/M

	
	
	
	.IF DSKY
;__KB_GET____________________________________________________________________________________________
;
;  Get a Single Key and Decode
;     
;____________________________________________________________________________________________________
KB_GET:
	PUSH 	HL			; STORE HL
KB_Get_Loop:				; WAIT FOR KEY
	CALL	KB_Scan			;  Scan KB Once
	CP	00H			;  Null?
	JR	Z,KB_Get_Loop		;  Loop while not zero
	LD      D,A			;  Store A
	LD	A,4FH			;  Scan All Col Lines
	OUT 	(PORTC),A		;  Send to Column Lines
        CALL    DELAY12			;  Delay to allow lines to stabilize
KB_Clear_Loop:				; WAIT FOR KEY TO CLEAR
	IN	A,(PORTB)		;  Get Rows
	CP	00H 			;  Anything Pressed?
	JR	NZ,KB_Clear_Loop	;  Yes, Exit.
	LD	A,D			;  Restore A
	LD	D,00H			;
	LD	HL,KB_Decode		;  Point to beginning of Table	
KB_Get_LLoop:
	CP	(HL)			;  Match?	
	JR	Z,KB_Get_Done		;  Found, Done
	INC	HL
	INC	D			;  D + 1	
	JP	NZ,KB_Get_LLoop		;  Not Found, Loop until EOT			
KB_Get_Done:
	LD	A,D			;  Result Into A
	POP	HL			; RESTORE HL
	RET



;__KB_Scan____________________________________________________________________________________________
;
;  SCan Keyboard Matrix for an input
;     
;____________________________________________________________________________________________________
KB_Scan:

	LD      C,0000H
	LD	A,41H			;  Scan Col One
	OUT 	(PORTC),A		;  Send to Column Lines
        CALL    DELAY12			;  Delay to allow lines to stabilize
	IN	A,(PORTB)		;  Get Rows
	CP	00H 			;  Anything Pressed?
	JR	NZ,KB_Scan_Found	;  Yes, Exit.

	LD      C,0040H
	LD	A,42H			;  Scan Col Two
	OUT 	(PORTC),A		;  Send to Column Lines
        CALL    DELAY12			;  Delay to allow lines to stabilize
	IN	A,(PORTB)		;  Get Rows
	CP	00H 			;  Anything Pressed?
	JR	NZ,KB_Scan_Found	;  Yes, Exit.

	LD      C,0080H
	LD	A,44H			;  Scan Col Three
	OUT 	(PORTC),A		;  Send to Column Lines
        CALL    DELAY12			;  Delay to allow lines to stabilize
	IN	A,(PORTB)		;  Get Rows
	CP	00H 			;  Anything Pressed?
	JR	NZ,KB_Scan_Found	;  Yes, Exit.

	LD      C,00C0H			;
	LD	A,48H			;  Scan Col Four
	OUT 	(PORTC),A		;  Send to Column Lines
        CALL    DELAY12			;  Delay to allow lines to stabilize
	IN	A,(PORTB)		;  Get Rows
	CP	00H 			;  Anything Pressed?
	JR	NZ,KB_Scan_Found	;  Yes, Exit.

	LD	A, 40H			;  Turn off All Columns
	OUT 	(PORTC),A		;  Send to Column Lines
	LD	A, 00H			;  RETURN NULL
	RET				;  Exit

KB_Scan_Found:
	AND	3FH			;  Clear Top two Bits
	OR	C			;  Add in Row Bits 
	LD	C,A			;  Store Value
	LD	A, 00H			;  Turn off All Columns
	OUT 	(PORTC),A		;  Send to Column Lines
	LD	A,C			;  Restore Value
	RET


;__DECODEDISPLAY_____________________________________________________________________________________
;
;  Display contents of DISPLAYBUF in decoded Hex bits 0-3 are displayed dig, bit 7 is DP
;     
;____________________________________________________________________________________________________
DECODEDISPLAY:
	PUSH	BC			; STORE BC
	PUSH	HL			; STORE HL
	LD	HL,SEGDECODE		; POINT HL TO DECODE TABLE
	LD	B,00H			; RESET HIGH BYTE
	LD	C,A			; CHAR INTO LOW BYTE
	ADD	HL,BC			; SET TABLE POINTER
	LD	A,(HL)			; GET VALUE
	POP	HL			; RESTORE HL
	POP	BC			; RESTORE BC
	RET


	
	
;__FLSEGDISPLAY________________________________________________________________________________________
;
;  Display contents of TRACK, SECTOR, ST0, ST1 ON DSKY
;     
;____________________________________________________________________________________________________
FLSEGDISPLAY:
	PUSH	AF			; STORE AF
	PUSH	BC			; STORE BC
	PUSH	HL			;
	LD	A,(pTRACK)		;
	AND	0FH			;
	LD	(DISPLAYBUF+6),A	;
	LD	A,(pTRACK)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+7),A	;			
	LD	A,(SECTOR)		;
	AND	0FH			;
	LD	(DISPLAYBUF+4),A	;
	LD	A,(SECTOR)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+5),A	;
	LD	A,(ST0)			;
	AND	0FH			;
	LD	(DISPLAYBUF+2),A	;
	LD	A,(ST0)			;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+3),A	;			
	LD	A,(ST1)			;
	AND	0FH			;
	LD	(DISPLAYBUF),A		;
	LD	A,(ST1)			;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+1),A	;
	LD	HL,DISPLAYBUF		;
	LD	BC,0007H		;
	ADD	HL,BC			;
	LD	B,08H			; SET DIGIT COUNT
	LD	A,40H			; set Control port 7218 to off
	OUT	(PORTC),A		; output
	CALL 	DELAY12			; wait
	LD	A,0D0H			; set control to 1111 (Data Coming, Hex Decode, Decode, Normal)
	JP	SEGDISPLAY1		;

;__SEGDISPLAY________________________________________________________________________________________
;
;  Display contents of DISPLAYBUF in decoded Hex bits 0-3 are displayed dig, bit 7 is DP
;     
;____________________________________________________________________________________________________
SEGDISPLAY:
	PUSH	AF			; STORE AF
	PUSH	BC			; STORE BC
	PUSH	HL			; STORE HL
	LD	BC,0007H	
	ADD	HL,BC
	LD	B,08H			; SET DIGIT COUNT
	LD	A,40H			; set Control port 7218 to off
	OUT	(PORTC),A		; output
	CALL 	DELAY12			; wait
	LD	A,0F0H			; set control to 1111 (Data Coming, Hex Decode,NO Decode, Normal)
SEGDISPLAY1:				;

	OUT	(PORTA),A		; output to port
	LD	A,80H			; Strobe write pulse with Control=1
	OUT	(PORTC),A		; output to port
	CALL 	DELAY12			; wait
	LD	A,40H			; set Control port 7218 to off
	OUT	(PORTC),A		; output
SEGDISPLAY_LP:		
	LD	A,(HL)			; GET DISPLAY DIGIT
	OUT	(PORTA),A		; OUT TO PORTA
	LD	A,00H			; SET WRITE STROBE
	OUT	(PORTC),A		; OUT TO PORTC
	CALL	DELAY12			; DELAY
	LD	A,40H			; SET CONTROL PORT OFF
	OUT	(PORTC),A		; OUT TO PORTC
	CALL	DELAY12			; WAIT
	DEC	HL			; INC POINTER
	DJNZ	SEGDISPLAY_LP		; LOOP FOR NEXT DIGIT
	POP	HL			; RESTORE HL
	POP	BC			; RESTORE BC
	POP	AF			; RESTORE AF
	RET
	.ENDIF

;__DELAY24__________________________________________________________________________________________________________________________ 
;
; 	DELAY 24US
;________________________________________________________________________________________________________________________________
;
	
DELAY24:	
					; JP= 10T	
	PUSH	IX			; 15T
	POP	IX			; 14T
	PUSH	IX			; 15T
	POP	IX			; 14T
DELAY12:
	PUSH	IX			; 15T
	POP	IX			; 14T
	RET				; 10T

	
	
;________________________________________________________________________________________________________________________________ 
;
;   ATAPI Code
;________________________________________________________________________________________________________________________________ 

;__ATAPI_READ_SECTOR_____________________________________________________________________________________________________________ 
;  READ ATAPI SECTOR   
;
;   D E H L = SECTOR (DOUBLE WORD) TO READ 
;   IX = READ TO ADDRESS 
;
;   ON RETURN IX WILL BE POINTED TO NEXT BYTE AFTER READ OPERATION 
;________________________________________________________________________________________________________________________________ 
ATAPI_READ_SECTOR:
	PUSH	BC			; STORE BC
	PUSH	DE			; STORE DE
	PUSH	HL			; STORE HL
	LD	A,D			; STORE SECTOR ADDRESS TO PACKET
	LD	(READ_DISK_PACKET+2),A	;
	LD	A,E			;
	LD	(READ_DISK_PACKET+3),A	;
	LD	A,H			;
	LD	(READ_DISK_PACKET+4),A	;
	LD	A,L			;
	LD	(READ_DISK_PACKET+5),A	;
	CALL	REQUEST_SENSE_LOOP	; GET ATAPI SENSE CODES TO CLEAR ERRORS
	LD	HL,READ_DISK_PACKET	; SET POINTER TO READ SECTOR PACKET
	CALL	ATAPI_SEND_PACKET	; SEND PACKET COMMAND
	CALL	ATAPI_READ_DATA		; 
	POP	HL			; RESTORE HL
	POP	DE			; RESTORE DE
	POP	BC			; RESTORE BC
	RET				;



;__ATAPI_SEND_PACKET_____________________________________________________________________________________________________________ 
;  SEND PACKET POINTED TO BY HL TO ATAPI DRIVE   
;
;________________________________________________________________________________________________________________________________ 
ATAPI_SEND_PACKET:

	CALL	IDE_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	CALL	IDE_WAIT_DRQ_ZERO	;
					;
	LD	A,0AH			;
	OUT	(IDECTRL),A		; Disable INT
	LD	A,00H			;
	OUT	(IDEERR),A		;
	LD	A,00H			;
	OUT	(IDESECTC),A		; 
	LD	A,00H			;
	OUT	(IDESECTN),A		;
	LD	A,00H			;
	OUT	(IDECYLLO),A		; 
	LD	A,60H			;
	OUT	(IDECYLHI),A		; 
	LD	A,(IDEDEVICE)		;
	OUT	(IDEHEAD),A		; Bit 4 selects device
	LD	A,0A0H			;
	OUT	(IDESTTS),A		;
					;
	CALL	IDE_WAIT_DRQ_READY	; MAKE SURE DRIVE IS READY TO PROCEED
					;
	LD	B,6			; SEND 12 BYTES (6 WORDS)
					;
ATAPI_SEND_PACKET_LOOP:
	LD	A,(HL)			; GET BYTE
	LD	D,A			; STORE LOW BYTE IN D
	INC	HL			; INC POINTER
	LD	A,(HL)			; GET HIGH BYTE
	OUT	(IDEHI),A		; STORE HIGH BYTE
	LD	A,D			; MOVE LOW BYTE INTO A
	OUT	(IDELO),A		; STORE LOW BYTE
	INC	HL			; INC POINTER
	IN	A,(IDECTRL)		; GET STATUS
	DJNZ	ATAPI_SEND_PACKET_LOOP	; LOOP
					;
	CALL	IDE_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	IN	A,(IDECTRL)		; READ STATUS (FOR DELAY)
					;
	RET				;




;__ATAPI_READ_DATA__________________________________________________________________________________________________________
;      READ DATA BLOCK INTO SECTOR_BUFFER
;
; IX = POINTER TO BUFFER
;
;___________________________________________________________________________________________________________________________

ATAPI_READ_DATA:
	LD	B,0			; 256 WORDS (512 BYTES PER SECTOR)
	CALL	IDE_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	IN	A,(IDESTTS)		; READ  REG
	AND	%00001000		; MASK OFF BIT
	CP	08H			; IS DATA WAITING?
	JR	NZ,ATAPI_READ_DATA_EXIT	; NO, EXIT
ATAPI_READ_DATA_LOOP:
	IN	A,(IDELO)		;
	LD	(IX),A			;
	INC	IX			;
	IN	A,(IDEHI)		;
	LD	(IX),A			;
	INC	IX			;
	DJNZ	ATAPI_READ_DATA_LOOP	;
ATAPI_READ_DATA_EXIT:
	RET				;

;__IDE_SOFT_RESET__________________________________________________________________________________________________________
;      RESET IDE DEVICE
;___________________________________________________________________________________________________________________________
IDE_SOFT_RESET:

	LD	A,%00001110		;NO INTERRUPTS, RESET DRIVE = 1
	OUT	(IDECTRL),A		;
	CALL	DELAY12			;
	LD	A,%00001010		;NO INTERRUPTS, RESET DRIVE = 0
	OUT	(IDECTRL),A		;
	CALL	IDE_WAIT_BUSY_READY	;
	RET

;___REQUEST_SENSE_LOOP____________________________________________________________________________________
;
;	ATAPI_REQUEST SENSE DATA
;_________________________________________________________________________________________________________			
REQUEST_SENSE_LOOP:
	PUSH	HL			;
	PUSH	IX			;
	PUSH	AF			;
	LD	HL,ATAPI_REQUEST_SENSE	;
	CALL	ATAPI_SEND_PACKET	;
	CALL	ATAPI_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	JP	NC,REQUEST_SENSE_EXIT	; ERROR, RETURN
	LD	B,0			; 256 WORDS (512 BYTES PER SECTOR)
REQUEST_SENSE_LOOP1:			;
	IN	A,(IDELO)		;
	INC	IX			;
	IN	A,(IDEHI)		;
	INC	IX			;
	DJNZ	REQUEST_SENSE_LOOP1	;
	RRD				; DELAY ONLY
	IN	A,(IDESTTS)		;READ ERROR REG
	AND	%00000001		;MASK OFF BIT
	JR	NZ,REQUEST_SENSE_LOOP	;
REQUEST_SENSE_EXIT:
	POP	AF			;
	POP	IX			;
	POP	HL			;
	RET

;___ATAPI_WAIT_BUSY_READY________________________________________________________________________________
;
;	WAIT FOR ATAPI CHANNEL TO BE READY
;________________________________________________________________________________________________________			
ATAPI_WAIT_BUSY_READY:
	LD	DE,0			; CLEAR OUT DE
ATAPI_WBSY:				;
	LD	B,5			; SETUP TIMEOUT
ATAPI_DLP:				;
	DJNZ	ATAPI_DLP		; 
	INC	DE			;
	LD	A,D			;
	OR	E			;
	JR	Z,ATAPI_TO		;
	IN	A,(IDESTTS)		; READ ERROR REG
	AND	%10000000		; MASK OFF BUSY BIT
	JR	NZ,ATAPI_WBSY		; WE WANT BUSY(7) TO BE 0 
	SCF				; CARRY 1 = OK
	RET				;
ATAPI_TO:				;
	XOR	A			; CARRY 0 = TIMED OUT
	RET				;



;__ATAPI_DEVICE_SELECTION___________________________________________________________________________________________________
; IDE SELECT DEVICE 
;___________________________________________________________________________________________________________________________
ATAPI_DEVICE_SELECTION:

	CALL	IDE_WAIT_BUSY_READY	;	
	LD	A,(IDEDEVICE)		; Selects Device
	OR	0A0H			;
	OUT	(IDEHEAD),A		;	
	CALL	IDE_WAIT_BUSY_READY	;
	RET				;


;__IDE_WAIT_BUSY_READY______________________________________________________________________________________________________
; WAIT FOR BUSY TO BE READY
;___________________________________________________________________________________________________________________________
IDE_WAIT_BUSY_READY:
	PUSH	DE			;
	PUSH 	BC			;
	LD	DE,0			;
IDE_WBSY:
	LD	B,5			;
IDE_DLP:
	DJNZ	IDE_DLP			;
	INC	DE			;
	LD	A,D			;
	OR	E			;
	JR	Z,IDE_TO		;
	IN	A,(IDESTTS)		; READ ERROR REG
	AND	%10000000		; MASK OFF BUSY BIT
	JR	NZ,IDE_WBSY		; WE WANT BUSY(7) TO BE 0 
	SCF				; CARRY 1 = OK
	POP	BC			;
	POP	DE			;
	RET				;
IDE_TO:
	POP	BC			;
	POP	DE			;
	XOR	A			; CARRY 0 = TIMED OUT
	RET				;
	

;__IDE_WAIT_DRDY_READY______________________________________________________________________________________________________
; WAIT FOR DRDY
;___________________________________________________________________________________________________________________________
IDE_WAIT_DRDY_READY:
	IN	A,(IDESTTS)		; READ ERROR REG
	AND	%01000000		; MASK OFF RDY BIT
	JR	Z,IDE_WAIT_DRDY_READY	; WE WANT RDY(6) TO BE 1 
	RET

;__IDE_WAIT_DRQ_READY_______________________________________________________________________________________________________
; WAIT FOR DRQ 
;___________________________________________________________________________________________________________________________
IDE_WAIT_DRQ_READY:
	IN	A,(IDESTTS)		; READ ERROR REG
	AND	%00001000		; MASK OFF RDY BIT
	JR	Z,IDE_WAIT_DRQ_READY	; WE WANT DRQ(3) TO BE 1
	RET

;__IDE_WAIT_DRQ_ZERO________________________________________________________________________________________________________
; WAIT FOR DRQ = 0
;___________________________________________________________________________________________________________________________
IDE_WAIT_DRQ_ZERO:
	IN	A,(IDESTTS)		; READ ERROR REG
	AND	%00001000		; MASK OFF RDY BIT
	JR	NZ,IDE_WAIT_DRQ_ZERO	; WE WANT DRQ(3) TO BE 0
	RET
	
;___READ_FLOPPY_SECTOR_____________________________________________________________________________________
;
;	READ A SECTOR FROM A FLOPPY DISK
;
;________________________________________________________________________________________________________
READ_FLOPPY_SECTOR:
	CALL	FLOPPYREAD		; READ THE FLOPPY DISK SECTOR
	LD	A,(ST0)			; GET STATUS FLAG 0
	AND	0F8H			; MASK OF DRIVE AND HEAD SELECTION
	LD	B,A			; MOVE STATUS FLAG 0 TO B
	LD	A,(ST1)			; GET STATUS FLAG 1
	OR	B			; IF ZERO READ WAS OK
	JP	NZ,READ_FLOPPY_SECTOR	;
	
	.IF	DSKY
	CALL	FLSEGDISPLAY		;
	.ENDIF
	RET
	
;__SETUPDRIVE__________________________________________________________________________________________________________________________ 
;
;	SETUP FLOPPY DRIVE SETTINGS 
;________________________________________________________________________________________________________________________________
;
;
;
SETUPDRIVE:
	LD	A,RESETL		; RESET SETTINGS
	OR	MINI			; SELECT MINI FLOPPY (low dens=1, high dens=0)
	OR	PRECOMP			; SELECT PRECOMP 
	OR	FDDENSITY		; SELECT DENSITY
	OR	FDREADY			; SELECT READY SIGNAL
	LD	(FLATCH_STORE),A	; SAVE SETTINGS
	LD	A,01H			;
	LD	(UNIT),A		; SET UNIT 1
	LD	A,2			; DENSITY
	LD	(DENS),A		;
	LD	A,09			;
	LD	(EOTSEC),A		; LAST SECTOR OF TRACK			
	LD	A,7FH			;
	LD	(SRTHUT),A		; STEP RATE AND HEAD UNLOAD TIME
	LD	A,05H			;
	LD	(HLT),A			; HEAD LOAD TIME
	LD	A,0DH			;
	LD	(GAP),A			; GAP 
	LD	A,80H			;
	LD	(SECSIZ),A		; SECTOR SIZE /4
					;
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
					;					
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	RES	1,(HL)			; SET MOTOR ON
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	NOP				;
	NOP				;
	LD	A,00H			; ZERO TRACK
	LD	(pTRACK),A		; STORE TRACK
	CALL	SETTRACK		; DO IT	
	NOP				;
	NOP				;
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	1,(HL)			; SET MOTOR OFF
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	RET
;
;__OUTFLATCH__________________________________________________________________________________________________________________________ 
;
;	SEND SETTINGS TO FLOPPY CONTROLLER
;________________________________________________________________________________________________________________________________
;
OUTFLATCH:
	LD	A,(FLATCH_STORE)	; SET A TO SETTINGS
	OUT	(FLATCH),A		; OUTPUT TO CONTROLLER
	RET

		
;__FLOPPYREAD__________________________________________________________________________________________________________________________ 
;
; 	READ A FLOPPY DISK SECTOR 	
;________________________________________________________________________________________________________________________________
;	
FLOPPYREAD:
	LD	A,46H			; BIT 6 SETS MFM, 06H IS READ COMMAND
	LD	(CMD),A			;
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	1,(HL)			; SET MOTOR OFF
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
					;
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CP	$FF			; DID IT RETURN WITH ERROR CODE?
	JP	Z,DSKEXIT		; IF YES, EXIT WITH ERROR CODE
					;	
	LD	A,(UNIT)		; GET DISK UNIT NUMBER
	AND	03H			; MASK FOR FOUR DRIVES.
	LD	B,A			; PARK IT IN B
	LD	A,(HEAD)		; GET HEAD SELECTION
	AND	01H			; INSURE SINGLE BIT
	RLA				;
	RLA				; MOVE HEAD TO BIT 2 POSITION
	OR	B			; OR HEAD TO UNIT BYTE IN COMMAND BLOCK
	LD	(UNIT),A		; STORE IN UNIT
					;
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	RES	1,(HL)			; SET MOTOR ON
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER	
					;
	LD	A,$03			; SPECIFY COMMAND
	CALL	PFDATA			; PUSH IT
	LD	A,(SRTHUT)		; STEP RATE AND HEAD UNLOAD TIME
	CALL	PFDATA			; PUSH THAT
	LD	A,(HLT)			;
	CALL	PFDATA			; PUSH THAT
					;
	CALL	SETTRACK		; PERFORM SEEK TO TRACK
					;
	JP	NZ,DSKEXIT		; IF ERROR, EXIT
					;
	LD	A,(CMD)			; WHAT COMMAND IS PENDING?
	OR	A			; SET FLAGS
	JP	DOSO4			; NO, MUST BE READ OR WRITE COMMAND
DSKEXIT:	
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	1,(HL)			; SET MOTOR OFF
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
					;
	OR	0FFH			; SET -1 IF ERROR
	RET

RESULT:
	LD	C,07H			; LOAD C WITH NUMBER OF STATUS BYTES
	LD	HL,ST0			; POINT TO STATS STORAGE
RS3:
	CALL	GFDATA			; GET FIRST BYTE
	LD	(HL),A			; SAVE IT
	INC	HL			; POINTER++
	DEC	C			; CC-1
	JP	NZ,RS3			; LOOP TIL C0
	LD	A,(ST0)			; LOAD STS0
	AND	0F8H			; MASK OFF DRIVE #
	LD	B,A			; PARK IT
	LD	A,(ST1)			; LOAD STS1
	OR	B			; ACC OR B ->ACC IF 0 THEN SUCCESS
					;
RSTEXIT:
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	1,(HL)			; SET MOTOR OFF
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
					;
	RET				; DONE RETURN TO CALLER.
	
	
DOSO4:
	LD	HL,(TEMPW)		; GET BUFFER ADDRESS TO HL
	
	LD	A,(SECSIZ)		; XFERLEN
	LD	C,A			; C WILL BE THE NUMBER OF TRANSACTIONS
					; DIVIDED BY 4
					;
	LD	A,(CMD)			;
	CALL	PFDATA			; PUSH COMMAND TO I8272
	LD	A,(UNIT)		;
	CALL	PFDATA			; 
	LD	A,(pTRACK)		;
	CALL	PFDATA			; 
	LD	A,(HEAD)		;
	CALL	PFDATA			; 
	LD	A,(SECTOR)		;
	CALL	PFDATA			; 
	LD	A,(DENS)		;
	CALL	PFDATA			; WHAT DENSITY
	LD	A,(EOTSEC)		;
	CALL	PFDATA			; ASSUME SC (SECTOR COUNT)  EOT
	LD	A,(GAP)			;
	CALL	PFDATA			; WHAT GAP IS NEEDED
	LD	A,(DTL)			; DTL, IS THE LAST COMMAND BYTE TO I8272
	CALL	PFDATAS
;

	;
; PERFORM READ
; LOOP EXECUTES 4X, THIS ALLOWS C RATHER THAN BC AS COUNTER
; SAVING A FEW TSTATES. MAKES UP TO 1024 BYTE SECTORS POSSIBLE.
; FROM READ TO READ MUST NOT EXCEED 25US WORST CASE MIN.
; (76T STATES FOR 3MHZ 8085) or (100 T STATES FOR 4MHZ Z80)
;

RDD_POLL:
FDC_READP0:
	IN	A,(FMSR)		;
	OR	A			; test if byte ready RQM1
	JP	P,FDC_READP0		;	
					;
	AND	$20			;
	JP	Z,DSKOPEND		;jump if in results mode
					;
	IN	A,(FDATA)		;
	LD	(HL),A			;
	INC	HL			;

FDC_READP1:
	IN	A,(FMSR)		;
	OR	A			;
	JP	P,FDC_READP1		;
					;
	AND	$20			;
	JP	Z,DSKOPEND		;
					;
	IN	A,(FDATA)		;
	LD	(HL),A			;
	INC	HL			;
					;
FDC_READP2:
	IN	A,(FMSR)		;
	OR	A			;
	JP	P,FDC_READP2		;
					;
	AND	$20			;
	JP	Z,DSKOPEND		;
					;
	IN	A,(FDATA)		;
	LD	(HL),A			;
	INC	HL			;
					;
FDC_READP3:
	IN	A,(FMSR)		; 11
	OR	A			; 4
	JP	P,FDC_READP3		; 10
					;
	AND	$20			; 7
	JP	Z,DSKOPEND		; 10
					;
	IN	A,(FDATA)		; 11
	LD	(HL),A			; 10
	INC	HL			; 11
					;
	DEC	C			; 4
	JP	NZ,FDC_READP0		; 11
DSKOPEND:
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	0,(HL)			; SET TC
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	NOP				;
	NOP				; 2 MICROSECOND DELAY
	RES	0,(HL)			; RESET TC
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	NOP				;
	NOP				; 2 MICROSECOND DELAY
	NOP				;
	NOP				; 2 MICROSECOND DELAY
	SET	1,(HL)			; TURN OFF MOTOR
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	JP	RESULT			; GET STATUS BYTES <RESULT PHASE>
	
		
;__SETTRACK__________________________________________________________________________________________________________________________ 
;
; 	SEEK TO A TRACK ON GIVEN UNIT
; 	A: TRACK #
;________________________________________________________________________________________________________________________________
;
SETTRACK:
	LD	A,(fTRACK)		; GET CURRENT HEAD TRACK
	LD	C,A
	LD	A,(pTRACK)		; GET TRACK
	OR	A			; SET FLAGS
	JP	Z,RECAL			; IF 0 PERFORM RECAL INSTEAD OF SEEK
	CP	C			;
	JP	Z,WAINT			; ALREADY THERE, ABORT
	LD	(fTRACK),A		; STORE TRACK
	LD	A,0FH			; SEEK COMMAND
	CALL	PFDATA			; PUSH COMMAND
	LD	A,(UNIT)		; SAY WHICH UNIT
	CALL	PFDATA			; SEND THAT
	LD	A,(pTRACK)		; TO WHAT TRACK
	CALL	PFDATA			; SEND THAT TOO
	JP	WAINT			; WAIT FOR INTERRUPT SAYING DONE
RECAL:
	LD	A,00H			;
	LD	(fTRACK),A		; STORE TRACK
	LD	A,07H			; RECAL TO TRACK 0
	CALL	PFDATA			; SEND IT
	LD	A,(UNIT)		; WHICH UNIT
	CALL	PFDATA			; SEND THAT TOO
;
WAINT:
;
	CALL	DELAYHSEC		; DELAY TO LET HEADS SETTLE BEFORE READ
					;
					; WAIT HERE FOR INTERRPT SAYING DONE
					; LOOP TIL INTERRUPT
	CALL	CHECKINT		; CHECK INTERRUPT STATUS
;
	RET
	
	
;__CYCLEFLOPPY__________________________________________________________________________________________________________________________ 
;
; 	SEEK TO TRACK 0, THEN BACK TO THE SELECTED TRACK.   
;	THIS CAN BE USED ON AN ERROR CONDITION TO VERIFY THAT HEAD IS ON SELECTED TRACK
; 	
;________________________________________________________________________________________________________________________________
;
CYCLEFLOPPY:
	PUSH	AF			; STORE	AF
	PUSH	HL			; STORE	HL
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	RES	1,(HL)			; SET MOTOR ON
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	NOP				;
	NOP				;
	CALL	RECAL			;
	CALL	DELAYHSEC		;
	CALL	DELAYHSEC		;
	CALL	DELAYHSEC		;
	CALL	DELAYHSEC		;
	CALL	RECAL			;
	CALL	DELAYHSEC		;
	CALL	DELAYHSEC		;
	CALL	DELAYHSEC		;
	CALL	DELAYHSEC		;
	CALL	SETTRACK		;
	CALL	DELAYHSEC		;
	CALL	DELAYHSEC		;
	CALL	DELAYHSEC		;
	CALL	DELAYHSEC		;
	POP	HL			;
	POP	AF			; RESTORE AF
	RET	

;__PFDATAS__________________________________________________________________________________________________________________________ 
;
; WRITE A COMMAND OR PARAMETER SEQUENCE
;
; TRANSFERS ARE SYNCHONIZED BYT MSR D7 <RQM> AND D6 <DIO>
;	RQM  DIO
;	0	0	BUSY
;	1	0	WRITE TO DATA REGISTER PERMITTED
;	1	1	BYTE FOR READ BY HOST PENDING
;	0	1	BUSY
;
;________________________________________________________________________________________________________________________________
;
PFDATAS:
	PUSH	AF			; STORE AF
PFDS1:
	IN	A,(FMSR)		; READING OR WRITING IS KEYS TO D7 RQM
	AND	80H			; MASK OFF RQM BIT 
	JP	Z,PFDS1			; WAIT FOR RQM TO BE TRUE.
	IN	A,(FMSR)		; READ STATUS
	AND	40H			; WAITING FOR INPUT?
	CALL	NZ,ERRORT		; NO, SIGNAL ERROR
	POP	AF			; RESTORE AF
	OUT	(FDATA),A		; OUTPUT A TO CONTROLLER
	RET		
	
;__PFDATA__________________________________________________________________________________________________________________________ 
;
; WRITE A COMMAND OR PARAMETER SEQUENCE
;
; TRANSFERS ARE SYNCHONIZED BYT MSR D7 <RQM> AND D6 <DIO>
;	RQM  DIO
;	0	0	BUSY
;	1	0	WRITE TO DATA REGISTER PERMITTED
;	1	1	BYTE FOR READ BY HOST PENDING
;	0	1	BUSY
;
;________________________________________________________________________________________________________________________________
;
PFDATA:
	PUSH	AF			; STORE AF
PFD1:
	IN	A,(FMSR)		; READING OR WRITING IS KEYS TO D7 RQM
	AND	80H			; MASK OFF RQM BIT 
	JP	Z,PFD1			; WAIT FOR RQM TO BE TRUE.
	IN	A,(FMSR)		; READ STATUS
	AND	40H			; WAITING FOR INPUT?
	CALL	NZ,ERRORT		; NO, SIGNAL ERROR
	POP	AF			; RESTORE AF
	OUT	(FDATA),A		; OUTPUT A TO CONTROLLER
	JP	DELAY24			; WAIT 24 US BEFORE READING FMSR AGAIN


;__CHECKINT__________________________________________________________________________________________________________________________ 
;
; CHECK FOR ACTIVE FDC INTERRUPTS BEFORE GIVING I8272 COMMANDS
; POLL RQM FOR WHEN NOT BUSY AND THEN SEND FDC
; SENSE INTERRUPT COMMAND.  IF IT RETURNS WITH NON ZERO
; ERROR CODE, PASS BACK TO CALLING ROUTINE FOR HANDLING
;________________________________________________________________________________________________________________________________
;
CHECKINT:
	IN	A,(FMSR)		; READING OR WRITING IS KEYS TO D7 RQM
	AND	80H			; MASK OFF RQM BIT
	JP	Z,CHECKINT		; WAIT FOR RQM TO BE TRUE. WAIT UNTIL DONE
	IN	A,(FMSR)		; READ STATUS
	AND	40H			; WAITING FOR INPUT?
	JP	NZ,CHECKINTDONE		; NO, SIGNAL ERROR
	CALL	SENDINT			; SENSE INTERRUPT COMMAND
CHECKINTDONE:
	RET				;
	

;__DELAYHSEC__________________________________________________________________________________________________________________________ 
;
; DELAY FOR 1/2 SECOND
;________________________________________________________________________________________________________________________________
;		
DELAYHSEC:
	LD	HL,00000H		; 65536
DELDM:
	NOP				; (4 T) 
	NOP				; (4 T)
	NOP				; (4 T)
	NOP				; (4 T)
	DEC	L			; (6 T)
	JP	NZ,DELDM		; (10 T) 24 T  8 MICROSECONDS AT 4 MHZ
	DEC	H			; (6 T)
	JP	NZ,DELDM		; (10 T) (8 US * 256) * 256  524288 US  .5 SECONDS
	RET

;__ERRORT__________________________________________________________________________________________________________________________ 
;
; ERROR HANDLING
;________________________________________________________________________________________________________________________________
;			
ERRORT:
	IN	A,(FDATA)		; CLEAR THE JUNK OUT OF DATA REGISTER
	IN	A,(FMSR)		; CHECK WITH RQM
	AND	80H			; IF STILL NOT READY, READ OUT MORE JUNK
	JP	Z,ERRORT		;
	LD	A,$FF			; RETURN ERROR CODE -1
					;
	RET
;__SENDINT__________________________________________________________________________________________________________________________ 
;
; SENSE INTERRUPT COMMAND
;________________________________________________________________________________________________________________________________
;			
SENDINT:
	LD	A,08H			; SENSE INTERRUPT COMMAND
	CALL	PFDATA			; SEND IT
	CALL	GFDATA			; GET RESULTS
	LD	(ST0A),A		; STORE THAT
	AND	$C0			; MASK OFF INTERRUPT STATUS BITS
	CP	$80			; CHECK IF INVALID COMMAND
	JP	Z,ENDSENDINT		; YES, EXIT
	CALL	GFDATA			; GET ANOTHER (STATUS CODE 1)
	LD	(ST1A),A		; SAVE THAT
	LD	A,(ST0A)		; GET FIRST ONE
	AND	0C0H			; MASK OFF ALL BUT INTERRUPT CODE 00 IS NORMAL
ENDSENDINT:
	RET				;ANYTHING ELSE IS AN ERROR


;__GFDATA__________________________________________________________________________________________________________________________ 
;
; GET DATA FROM FLOPPY CONTROLLER
;
; TRANSFERS ARE SYNCHONIZED BYT MSR D7 <RQM> AND D6 <DIO>
;	RQM  DIO
;	0	0	BUSY
;	1	0	WRITE TO DATA REGISTER PERMITTED
;	1	1	BYTE FOR READ BY HOST PENDING
;	0	1	BUSY
;
;________________________________________________________________________________________________________________________________
;		
GFDATA:
	IN	A,(FMSR)		; READ STATUS BYTE
	AND	80H			; MASK OFF RQM
	JP	Z,GFDATA		; LOOP WHILE BUSY
	IN	A,(FMSR)		; READ STSTUS BUTE
	AND	40H			; MASK OFF DIO
	CALL	Z,ERRORT		; IF WRITE EXPECTED RUN ERRORRT
	IN	A,(FDATA)		; READ DATA
	JP	DELAY24			; WAIT 24 US BEFORE READING FMSR AGAIN

	.IF DSKY
		
;__DSPSECTOR_______________________________________________________________________________________________________________________ 
;
;	DISPLAY SECTOR IN HL ON FRONT PANEL
;________________________________________________________________________________________________________________________________
;
DSPSECTOR:
	PUSH	BC			; STORE BC
	PUSH	HL			; STORE HL
	LD	A,H			; DISPLAY HIGH BYTE, HIGH NIBBLE
	SRL 	A			;	
	SRL 	A			;	
	SRL 	A			;	
	SRL 	A			;	
	AND	0FH			;
	CALL 	DECODEDISPLAY		;
	LD	(SEC+3),A		;
	LD      A,H			; DISPLAY HIGH BYTE, LOW NIBBLE
	AND	0FH			;
	CALL 	DECODEDISPLAY		;
	LD	(SEC+2),A		;
	LD	A,L			; DISPLAY LOW BYTE, HIGH NIBBLE
	AND	0F0H			;
	SRL 	A			;	
	SRL 	A			;	
	SRL 	A			;	
	SRL 	A			;		
	AND	0FH			;
	CALL 	DECODEDISPLAY		;
	LD	(SEC+1),A		; DISPLAY LOW BYTE, LOW NIBBLE
	LD      A,L			;
	AND	0FH			;
	CALL 	DECODEDISPLAY		;
	LD	(SEC),A			;
	LD	HL,SEC			; DISPLAY PROMPT
	CALL	SEGDISPLAY		; 
	POP	HL			; RESTORE HL
	POP	BC			; RESTORE BC
	RET
	.ENDIF

	
;___IDE_READ_SECTOR______________________________________________________________________________________
;
;	READ IDE SECTOR
;________________________________________________________________________________________________________			
IDE_READ_SECTOR:
	CALL	IDE_WAIT_BUSY_READY 	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	CALL	IDE_SETUP_LBA		; TELL DRIVE WHAT SECTOR IS REQUIRED
	LD	A,20H			;
	OUT	(IDESTTS),A		; $20 = IDE 'READ SECTOR' COMMAND 
IDE_SREX:				;
	CALL	IDE_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	CALL	IDE_TEST_ERROR		; ENSURE NO ERROR WAS REPORTED
	RET	NC			; ERROR, RETURN
	CALL	IDE_WAIT_BUFFER		; WAIT FOR FULL BUFFER SIGNAL FROM DRIVE
	RET	NC			; ERROR, RETURN
	CALL	IDE_READ_BUFFER		; GRAB THE 256 WORDS FROM THE BUFFER
	SCF				; CARRY = 1 ON RETURN = OPERATION OK
IDE_READ_SECTOR_OK:			;
	SCF				; CARRY = 1 ON RETURN = OPERATION OK
	RET
;___IDE_READ_BUFFER_______________________________________________________________________________________
;
;	READ IDE BUFFER
;________________________________________________________________________________________________________			
IDE_READ_BUFFER:
	LD	B,0			; 256 WORDS (512 BYTES PER SECTOR)
IDEBUFRD:				;
	IN	A,(IDELO)		; LOW BYTE OF WORD FIRST	
	LD	(IX),A			;
	INC	IX			;
	IN	A,(IDEHI)		; THEN HIGH BYTE OF WORD
	LD	(IX),A			;
	INC	IX			;
	DEC	B			;
	JP	NZ,IDEBUFRD		;
	RET
	
;___IDE_SETUP_LDA________________________________________________________________________________________
;
;	SETUP IDE DRIVE FOR LDA OPERATION
;________________________________________________________________________________________________________			
IDE_SETUP_LBA:
	LD	A,L			; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ
	LD	(IDE_LBA0),A		;
	LD	A,H			; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ
	LD	(IDE_LBA1),A		;
	LD	A,0000H		 	; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ
	LD	(IDE_LBA2),A		;
	AND	%00001111		; ONLY LOWER FOUR BITS ARE VALID
	ADD	A,%11100000		; ENABLE LBA BITS 5:7=111 IN IDE_LBA3
	LD	(IDE_LBA3),A		;
					; READ IDE HD SECTOR
	LD	A,1			;
	OUT	(IDESECTC),A		; SET SECTOR COUNT = 1	
					;	
	LD	A,(IDE_LBA0)		;
	OUT	(IDESECTN),A		; SET LBA 0:7
					;
	LD	A,(IDE_LBA1)		;
	OUT	(IDECYLLO),A		; SET LBA 8:15
					;
	LD	A,(IDE_LBA2)		;
	OUT	(IDECYLHI),A		; SET LBA 16:23
					;
	LD	A,(IDEDEVICE)		; Selects Device
	LD	C,A			;				
	LD	A,(IDE_LBA3)		;
	AND	%00001111		; LOWEST 4 BITS USED ONLY
	OR	%11100000		; TO ENABLE LBA MODE
	OR	C			;
	OUT	(IDEHEAD),A		; SET LBA 24:27 + BITS 5:7=111
	RET	
	
;___IDE_TEST_ERROR_______________________________________________________________________________________
;
;	CHECK FOR IDE ERROR CONDITION
;________________________________________________________________________________________________________			
IDE_TEST_ERROR:
	SCF				;
	IN	A,(IDESTTS)		;
	LD	B,A			; 
	AND	%00000001		; TEST ERROR BIT
	SCF				; 
	RET	Z			;
	LD	A,B			; 
	AND	%00100000		;
	SCF				;
	JP	NZ,IDE_ERR		; TEST WRITE ERROR BIT
	IN	A,(IDEERR)		; READ ERROR FLAGS
IDE_ERR:
	OR	A			; CARRY 0 = ERROR
	RET				; IF A = 0, IDE BUSY TIMED OUT

;___IDE_WAIT_BUFFER_______________________________________________________________________________________
;
;	WAIT FOR DATA BUFFER READY
;________________________________________________________________________________________________________			
IDE_WAIT_BUFFER:
	LD	DE,0			;
IDE_WDRQ:				;
	LD	B,5			;
IDE_BLP:				;
	DEC	B			;
	JP	NZ,IDE_BLP		;	
	INC	DE			;
	LD	A,D			;
	OR	E			;
	JP	Z,IDE_TO2		;
	IN	A,(IDESTTS)		; WAIT FOR DRIVE'S 512 BYTE READ BUFFER 
	AND	%00001000		; TO FILL (OR READY TO FILL)
	JP	Z,IDE_WDRQ		;
	SCF				; CARRY 1 = OK
	RET				;
IDE_TO2:				;
	XOR	A			; CARRY 0 = TIMED OUT
	RET				;
	
	
	
	
	
	
	
	.IF UART	
;__SPACE_________________________________________________________________________________________________________________________ 
;
;	PRINT A SPACE CHARACTER ON THE SERIAL PORT
;________________________________________________________________________________________________________________________________
;
SPACE:
	PUSH	AF			; Store AF
	LD	A,20H			; LOAD A "SPACE"
	CALL	COUT			; SCREEN IT
	POP	AF			; RESTORE AF
	RET				; DONE


;__COUT__________________________________________________________________________________________________________________________ 
;
;	Write the Value in "A" to the Serial Port
;________________________________________________________________________________________________________________________________
;
COUT:
	PUSH   AF			; Store AF
TX_BUSYLP:
	IN	A,(UART5)		; READ Line Status Register
	BIT	5,A			; TEST IF UART IS READY TO SEND
	JP	Z,TX_BUSYLP		; IF NOT REPEAT
	POP	AF			; Restore AF
	OUT	(UART0),A		; THEN WRITE THE CHAR TO UART
	RET				; DONE


;__CRLF__________________________________________________________________________________________________________________________ 
;
;	Send CR & LF to the Serial Port
;________________________________________________________________________________________________________________________________
;
CRLF:
	PUSH	HL			; protect HL from overwrite
	LD	HL,TCRLF		; Load Message Pointer
	CALL	MSG			; Sebd Message to Serial Port
	POP	HL			; protect HL from overwrite
	RET				;
;__MSG___________________________________________________________________________________________________________________________ 
;
;	Print a String  to the serial port
;________________________________________________________________________________________________________________________________
;
MSG:

TX_SERLP:
	LD	A,(HL)			; GET CHARACTER TO A
	CP	END			; TEST FOR END BYTE
	JP	Z,TX_END		; JUMP IF END BYTE IS FOUND
	CALL	COUT			;
	INC	HL			; INC POINTER, TO NEXT CHAR
	JP	TX_SERLP		; TRANSMIT LOOP
TX_END:
	RET				;ELSE DONE


TCRLF:
	.BYTE	CR,LF,END

;
;__Init_UART_____________________________________________________________________________________________________________________ 
;
;	Initialize UART
;	Params:	SER_BAUD Needs to be set to Baud Rate
;	1200:	96	 = 1,843,200 / ( 16 x 1200 )
;	2400:	48	 = 1,843,200 / ( 16 x 2400 )
;	4800:	24	 = 1,843,200 / ( 16 x 4800 )
;	9600:	12	 = 1,843,200 / ( 16 x 9600 )
;	19K2:	06	 = 1,843,200 / ( 16 x 19,200 )
;	38K4:	03	
;	57K6:	02
;	115K2:	01	
;
;_________________________________________________________________________________________________________________________________
;
INIT_UART:
	LD	A,80H			;
	OUT	(UART3),A		; SET DLAB FLAG
	LD	A,(SER_BAUD)		;
	OUT	(UART0),A		;
	LD	A,00H			;
	OUT	(UART1),A		;
	LD	A,03H			;
	OUT	(UART3),A		; Set 8 bit data, 1 stopbit
	RET
;__CRLFA_________________________________________________________________________________________________________________________ 
;
;	Print Command Prompt to the serial port
;________________________________________________________________________________________________________________________________
;
CRLFA:
	PUSH	HL			; protect HL from overwrite
	LD	HL,PROMPT		;
	CALL	MSG			;
	POP	HL			; protect HL from overwrite
	RET				; DONE
;__GETLN_________________________________________________________________________________________________________________________ 
;
;	Read a line(80) of text from the Serial Port, handle <BS>, term on <CR>.
;       Exit if too many chars.   Store result in HL.  Char count in C.
;________________________________________________________________________________________________________________________________
;
GETLN:
	LD	C,00H			; ZERO CHAR COUNTER
	PUSH	DE			; STORE DE
GETLNLOP:
	CALL	KIN			; GET A KEY
	CALL	COUT			; OUTPUT KEY TO SCREEN
	CP	CR			; IS <CR>?
	JR	Z,GETLNDONE		; YES, EXIT 
	CP	BS			; IS <BS>?
	JR	NZ,GETLNSTORE		; NO, STORE CHAR
	LD	A,C			; A=C
	CP	0			;
	JR	Z,GETLNLOP		; NOTHING TO BACKSPACE, IGNORE & GET NEXT KEY
	DEC	HL			; PERFORM BACKSPACE
	DEC	C			; LOWER CHAR COUNTER	
	LD	A,0			;
	LD	(HL),A			; STORE NULL IN BUFFER
	LD	A,20H			; BLANK OUT CHAR ON TERM
	CALL	COUT			;
	LD	A,BS			;
	CALL	COUT			;
	JR	GETLNLOP		; GET NEXT KEY
GETLNSTORE:
	LD	(HL),A			; STORE CHAR IN BUFFER
	INC	HL			; INC POINTER
	INC	C			; INC CHAR COUNTER	
	LD	A,C			; A=C
	CP	4DH			; OUT OF BUFFER SPACE?
	JR	NZ,GETLNLOP		; NOPE, GET NEXT CHAR
GETLNDONE:
	LD	(HL),00H		; STORE NULL IN BUFFER
	POP	DE			; RESTORE DE
	RET				;
;__KIN___________________________________________________________________________________________________________________________ 
;
;	Read from the Serial Port and Echo & convert input to UCASE
;________________________________________________________________________________________________________________________________
;
KIN:
	IN	A,(UART5)		; READ Line Status Register
	BIT	0,A			; TEST IF DATA IN RECEIVE BUFFER
	JP	Z,KIN			; LOOP UNTIL DATA IS READY
	IN	A,(UART0)		; THEN READ THE CHAR FROM THE UART
	AND	7FH			; STRIP HI BIT
	CP	'a'			; KEEP NUMBERS, CONTROLS
	RET	C			; AND UPPER CASE
	CP	7BH			; SEE IF NOT LOWER CASE
	RET	NC			; 
	AND	5FH			; MAKE UPPER CASE
	RET


	.ENDIF


;
;__Text_Strings_________________________________________________________________________________________________________________ 
;
;	System Text Strings
;_____________________________________________________________________________________________________________________________
;
	.IF DSKY
BOOT:
	.DB 	00H,00H,80H,80H,094H,09DH,09DH,09FH
	.ENDIF
	.IF UART
PROMPT:
	.BYTE	CR,LF,'>',END

MSG_START:
	.DB	LF,CR			; LINE FEED AND CARRIAGE RETURN
	.TEXT	"N8VEM BOOT LOADER"
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN

	.TEXT	"0->DSKY MONITOR"
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN
	.TEXT	"1->SERIAL MONITOR"
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN
	.TEXT	"2->BOOT CP/M ROM IMAGE"
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN
	.TEXT	"3->BOOT FLOPPY UNIT 0"
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN
	.TEXT	"4->BOOT FLOPPY UNIT 1"
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN
	.TEXT	"5->BOOT IDE PRIMARY"
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN
	.TEXT	"6->BOOT IDE SECONDARY"
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN
	.TEXT	"7->BOOT ATAPI PRIMARY"
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN
	.TEXT	"8->BOOT ATAPI SECONDARY"
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN
	.DB	END			; LINE TERMINATOR
	.ENDIF

;_ATAPI COMMAND PACKETS______________________________________________________________________________________________________
; 
;
READ_DISK_PACKET
	.DB	0A8H,00H,00H,00H,00H,01H,00H,00H,00H,01H,00H,00H
ATAPI_REQUEST_SENSE
	.DB	03H,00H,00H,00H,011H,00H,00H,00H,00H,00H,00H,00H
	
	
	.IF DSKY	
;_KB Decode Table__________________________________________________________________________________________________________
; 
;
KB_Decode:
;                0  1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
	.DB	41H,02H,42H,82H,04H,44H,84H,08H,48H,88H,10H,50H,90H,20H,60H,0A0H
;               FW  BK  CL  EN  DP  EX  GO  BO
	.DB	01H,81H,0c1H,0c2H,0c4H,0c8H,0D0H,0E0H
	
SEC:
	.DB 	80H,80H,80H,80H,80H,0CBH,0CFH,0D7H
	
;
; F-Keys,
; FW = Forward
; BK = Backward
; CL = Clear
; EN = Enter
; DP = Deposit (into mem)
; EX = Examine (Mem)
; GO = GO
; BO = Boot
;_________________________________________________________________________________________________________________________
;_HEX 7_SEG_DECODE_TABLE__________________________________________________________________________________________________
; 
; 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, ,-
; AND with 7FH to turn on DP.
;_________________________________________________________________________________________________________________________
SEGDECODE:
	.DB	0FBH,0B0H,0EDH,0F5H,0B6H,0D7H,0DFH,0F0H,0FFH,0F7H,0FEH,09FH,0CBH,0BDH,0CFH,0CEH,080H,084H,00H,0EEH,09DH
	
	.ENDIF
			
;	.ORG	$00FF
;FLAG	.db	$FF



;
;__Work_Area___________________________________________________________________________________________________________________ 
;
;	Reserved Ram For Monitor working area
;_____________________________________________________________________________________________________________________________
;
KEYBUF:  	.TEXT "                                                                                "
SER_BAUD:	.DS	1		; specify desired UART com rate in bps
DISPLAYBUF:	.DB 	00,00,00,00,00,00,00,00
IDEDEVICE:	.DB	1		; IDE DRIVE SELECT FLAG (00H=PRIAMRY, 10H = SECONDARY)
;
; DISK COMMAND BLOCK
;
CMD:		.DB	0			; COMMAND READ OR WRITE,
UNIT:		.DB	0			; PHYSICAL DRIVE 0->3
HEAD:		.DB	0			; HEAD SEL 0 OR 1
DENS:		.DB	2			; DENSITY
EOTSEC:		.DB	09			; LAST SECTOR OF TRACK
GAP:		.DB	1BH			; VALUE FOR IRG <GAP3>
SECSIZ:		.DB	080H			; HOW MANY BYTES TO TRANSFER/4
DTL:		.DB	0FFH			; SIZE OF SECTOR
SRTHUT:		.DB	7FH			; STEP RATE AND HEAD UNLOAD TIME
HLT:		.DB	05H			; HEAD LOAD TIME
MIN:		.DB	MINI			; LATCH BIT PATTERN FOR FDC9229 MINITRUE
PRE:		.DB	PRECOMP			; LATCH BIT PATTERN FOR FDC9229 PRECOMP125NS

;
; FLOPPY STATUS RESULT STORAGE
;
ST0:		.DB	0			; STORE STATUS 0
ST1:		.DB	0			; ST1
ST2:		.DB	0			; ST2
SCYL:		.DB	0			; TRACK
SHEAD:		.DB	0			; HEAD 0 OR 1
SREC:		.DB	0			; SECTOR
SNBIT:		.DB	0			; DENSITY
ST0A:		.DB	0			; STORE STATUS 0
ST1A:		.DB	0			; ST1
RETRY		.DB	0			; RETRIES
RETRY1		.DB	0			; RETRIES

FLATCH_STORE:
		.DB	00
SECTOR		.DB	00		; SECTOR NUMBER STORAGE		
pTRACK:		.DW 0			; TWO BYTES FOR TRACK # (PHYSICAL)
fTRACK:		.DW 0			; TWO BYTES FOR TRACK # (Floppy head)
TEMPW:		.DW 0			; TWO BYTES FOR TEMP WORD
IDE_LBA0:
		.DB 0			; SET LBA 0:7
IDE_LBA1:
		.DB 0			; SET LBA 8:15
IDE_LBA2:
		.DB 0			; SET LBA 16:23
IDE_LBA3:
		.DB 0			; LOWEST 4 BITS USED ONLY TO ENABLE LBA MODE 

SECTOR_BUFFER:	.DS	$0200


.END
